package com.zlq.cn.http;

import com.google.gson.annotations.SerializedName;
import com.zlq.cn.entity.Riddle;
import lombok.AllArgsConstructor;
import lombok.Data;
import okhttp3.*;
import okhttp3.logging.HttpLoggingInterceptor;
import one.util.streamex.StreamEx;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.http.GET;
import retrofit2.http.Query;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author zhoucl
 * @date 2021/9/2 17:41
 */
@Component
public final class RouteApiConfig {

    private static final String SHOWAPI_APPID = "showapi_appid";

    private static final String SHOWAPI_SIGN = "showapi_sign";

    private static final String APPID = "755216";

    private static final String SIGN = "f7d69b5b05024eb1ab6ff6f1601b9561";

    @Bean
    public ShowApiService showApiService() {
        return new Retrofit.Builder()
                .client(new OkHttpClient.Builder()
                        .addInterceptor(new Interceptor() {
                            @Override
                            public Response intercept(Chain chain) throws IOException {
                                Request request = chain.request();
                                HttpUrl url = request.url();
                                Set<String> names = url.queryParameterNames();
                                List<ParamData> paramDatas = new ArrayList<>();
                                int index = 0;
                                for (String name : names) {
                                    paramDatas.add(new ParamData(name, url.queryParameterValue(index)));
                                    index++;
                                }
                                paramDatas.add(new ParamData(SHOWAPI_APPID, APPID));
                                paramDatas = StreamEx.of(paramDatas)
                                        .sortedBy(ParamData::getName)
                                        .toList();
                                StringBuilder sb = new StringBuilder();
                                for (ParamData paramData : paramDatas) {
                                    sb.append(paramData.name).append(paramData.value);
                                }
                                sb.append(SIGN);
                                String sign = DigestUtils.md5DigestAsHex(sb.toString().getBytes(StandardCharsets.UTF_8));
                                HttpUrl.Builder urlBuilder = url.newBuilder();
                                urlBuilder.addEncodedQueryParameter(SHOWAPI_APPID, APPID);
                                urlBuilder.addEncodedQueryParameter(SHOWAPI_SIGN, sign);
                                Request.Builder builder = request.newBuilder();
                                return chain.proceed(builder.url(urlBuilder.build()).build());
                            }
                        })
                        .addInterceptor(new HttpLoggingInterceptor(System.out::println).setLevel(HttpLoggingInterceptor.Level.BODY))
                        .build())
                .baseUrl("http://route.showapi.com")
                .addConverterFactory(GsonConverterFactory.create())
//                .addConverterFactory(ScalarsConverterFactory.create())
                .build()
                .create(ShowApiService.class);
    }

    @Data
    public static class ShowApiCommonResult<T> {

        @SerializedName("showapi_res_error")
        private String showapiResError;

        @SerializedName("showapi_res_id")
        private String showapiResId;

        @SerializedName("showapi_res_code")
        private String showapiResCode;

        @SerializedName("showapi_fee_num")
        private String showapiResNum;

        @SerializedName("showapi_res_body")
        private T showapiResBody;

    }

    @Data
    public static class RiddleResult<T> {

        @SerializedName("ret_code")
        private Integer retCode;

        private RiddlePageResult<T> pb;
    }

    @Data
    public static class RiddlePageResult<T> {

        private Integer allNum;

        private Integer allPages;

        private Integer currentPage;

        private Integer maxResult;

        private List<T> contentlist;
    }

    @Data
    @AllArgsConstructor
    static class ParamData {

        private String name;

        private String value;
    }

    public interface ShowApiService {
        /**
         * typeId	String
         * 搞笑=gxmy,
         * 字谜=zmmy,
         * 成语=cymy,
         * 动物=dwmy,
         * 爱情=aqmy,
         * 灯谜=dmmy,
         * 人名=rmmy,
         * 地名=dimmy,
         * 词语=cy,
         * 带格=dgmy,
         * 用语=ry,
         * 儿童=etmy,
         * 物品=wpmy,
         * 植物=zwmy,
         * 名谜=jmmy,
         * 书报=sbmy,
         * 俗语=symy,
         * 药品=ypmy,
         * 音乐=yymy,
         * 影视=ysmy,
         * 称谓=cwmy,
         * 趣味=qtmy,
         * 精选=miyujingxuan,
         * 脑筋急转弯=njmy,
         * 智力问答=zlmy
         */
        @GET("/151-4")
        retrofit2.Call<ShowApiCommonResult<RiddleResult<Riddle>>> query(@Query("typeId") String typeId,
                                                                        @Query("page") Integer page);
    }
}
